package testcase.command;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.NoSuchElementException;

import junit.framework.TestCase;

import org.junit.Test;

import satir.card.Choice;
import satir.card.Question;
import satir.cell.ActionCell;
import satir.command.AskQuestionCmd;
import satir.player.Player;
import testcase.command.AskQuestionCmd_execute_1.PlayerStub;


public class AskQuestionCmd_execute_2 extends TestCase{
	
	/*
	 * Test Case: 1
	 * Objective: Test whether it will award correct Self-Esteem value for Q1 C1 to player or not
	 */
	@Test 
	public void testQuestion1C1AwardSEValue(){
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};
		ArrayList<Choice> choices;
		choices = new ArrayList<Choice>();
		choices.add(new Choice(
				"Blame him/her and prohibit use the phone more than 5 mins.",
				1, new Hashtable<String, Integer>()));
		choices.add(new Choice("Talk with son/daughter and find the reason.",
				1, new Hashtable<String, Integer>()));
		choices.add(new Choice(
				"Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.",
				-1, new Hashtable<String, Integer>()));
		choices.add(new Choice("Ignore him/her.", -1,
				new Hashtable<String, Integer>()));
		
		// give a question
		String question1 = "Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?";
		PlayerStub playerStub = new PlayerStub();
		Question question = new Question(question1, choices);

		// create questions array
		ArrayList<Question> questions = new ArrayList<Question>();
		questions.add(question);
		
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(question, playerStub);

		String input = "1";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(6,result);
	}
	/*
	 * Test Case: 2
	 * Objective: Test whether it will award correct Self-Esteem value for Q1 C2 to player or not
	 */
	@Test 
	public void testQuestion1C2AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("Blame him/her and prohibit use the phone more than 5 mins.", 1));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.", -1));
				choices.add(new ChoiceStub("Ignore him/her.", -1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "2";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(6,result);
	}
	
	/*
	 * Test Case: 3
	 * Objective: Test whether it will award correct Self-Esteem value for Q1 C3 to player or not
	 */
	@Test 
	public void testQuestion1C3AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("Blame him/her and prohibit use the phone more than 5 mins.", 1));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.", -1));
				choices.add(new ChoiceStub("Ignore him/her.", -1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "3";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(4,result);
	}
	
	/*
	 * Test Case: 4
	 * Objective: Test whether it will award correct Self-Esteem value for Q1 C4 to player or not
	 */
	@Test 
	public void testQuestion1C4AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("Blame him/her and prohibit use the phone more than 5 mins.", 1));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.", -1));
				choices.add(new ChoiceStub("Ignore him/her.", -1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "4";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(4,result);
	}
	
	/*
	 * Test Case: 5
	 * Objective: Test whether it will award correct Self-Esteem value for Q2 C1 to player or not
	 */
	@Test 
	public void testQuestion2C1AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Your children is facing the examination, Father prohibits his/her go outside since his/her Chinese subject result is only got 60 marks\nBut he/she is invited to attend the brithday party on this Saturday. As childern, What is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("You decide to go and lie to parent.", -2));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("You will discuss with parent about the revision time.", 5));
				choices.add(new ChoiceStub("Ask bother or sister to give advice.", 1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "1";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(3,result);
	}
	
	/*
	 * Test Case: 6
	 * Objective: Test whether it will award correct Self-Esteem value for Q2 C2 to player or not
	 */
	@Test 
	public void testQuestion2C2AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Your children is facing the examination, Father prohibits his/her go outside since his/her Chinese subject result is only got 60 marks\nBut he/she is invited to attend the brithday party on this Saturday. As childern, What is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("You decide to go and lie to parent.", -2));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("You will discuss with parent about the revision time.", 5));
				choices.add(new ChoiceStub("Ask bother or sister to give advice.", 1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "2";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(6,result);
	}
	
	/*
	 * Test Case: 7
	 * Objective: Test whether it will award correct Self-Esteem value for Q2 C3 to player or not
	 */
	@Test 
	public void testQuestion2C3AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Your children is facing the examination, Father prohibits his/her go outside since his/her Chinese subject result is only got 60 marks\nBut he/she is invited to attend the brithday party on this Saturday. As childern, What is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("You decide to go and lie to parent.", -2));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("You will discuss with parent about the revision time.", 5));
				choices.add(new ChoiceStub("Ask bother or sister to give advice.", 1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "3";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(10,result);
	}
	
	/*
	 * Test Case: 8
	 * Objective: Test whether it will award correct Self-Esteem value for Q2 C4 to player or not
	 */
	@Test 
	public void testQuestion2C4AwardSEValue(){
		
		class ChoiceStub extends Choice{
			private int rewardSE;
			String content;
			public ChoiceStub(String content, int rewardSE) {
				super("", 0, new Hashtable<String, Integer>());
				this.content = content;
				this.rewardSE = rewardSE;
			}
			
			@Override
			public String getContent(){
				return content;				
			}
			@Override
			public int getRewardSE() {
		        return rewardSE;
		    }
		};
		class QuestionStub extends Question{
			
			public QuestionStub() {
				super (null, null);
			}
			private ArrayList<Choice> choices;
			@Override
			public String getQuestion(){
				return "Your children is facing the examination, Father prohibits his/her go outside since his/her Chinese subject result is only got 60 marks\nBut he/she is invited to attend the brithday party on this Saturday. As childern, What is your decision?";
			}
			
			@Override
			public ArrayList<Choice> getChoices() {
				choices = new ArrayList<Choice>();
				choices.add(new ChoiceStub("You decide to go and lie to parent.", -2));
				choices.add(new ChoiceStub("Talk with son/daughter and find the reason.", 1));
				choices.add(new ChoiceStub("You will discuss with parent about the revision time.", 5));
				choices.add(new ChoiceStub("Ask bother or sister to give advice.", 1));
				return choices;
			}
		};
		
		class PlayerStub extends Player{
			private int selfEsteem;
			public PlayerStub(){
				selfEsteem=5;
			}
			@Override
			public void increaseSelfEsteem(int increaseValue){
				selfEsteem+=increaseValue;
			}
			
			public int getValue (){
				return selfEsteem;
			}
		};

//		ChoiceStub choiceStub = new ChoiceStub(null,0);
//		ArrayList<ChoiceStub> choices;	
		PlayerStub playerStub = new PlayerStub();
		QuestionStub questionStub = new QuestionStub();
		AskQuestionCmd askQuestionCmd = new AskQuestionCmd(questionStub, playerStub);

		String input = "4";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		int result = playerStub.getValue();
		assertEquals(6,result);
	}
}